/**
 * HTTP 请求工具
 * 封装了基于 fetch 的请求方法，支持环境变量配置
 */

import router from '@/router'

// 获取环境变量
const API_BASE_URL = import.meta.env.VITE_API_BASE_URL || '/api'
const USE_MOCK = import.meta.env.VITE_USE_MOCK === 'true'
const APP_ENV = import.meta.env.VITE_APP_ENV || 'development'

// 用于标记是否已经跳转到登录页，避免重复跳转
let isRedirectingToLogin = false

console.log('当前环境:', APP_ENV)
console.log('API 基础路径:', API_BASE_URL)
console.log('是否使用 Mock:', USE_MOCK)

/**
 * 统一请求方法
 * @param {string} url - 请求地址
 * @param {object} options - 请求配置
 * @returns {Promise} 响应数据
 */
async function request(url, options = {}) {
  // 如果开启 Mock，直接返回 Mock 数据（开发阶段）
  if (USE_MOCK && APP_ENV === 'development') {
    console.log('[Mock] 请求:', url, options)
    // 这里可以导入 Mock API 返回测试数据
    return Promise.resolve({
      code: 200,
      message: '操作成功(Mock)',
      data: null
    })
  }

  // 构建完整的请求URL
  const fullUrl = url.startsWith('http') ? url : `${API_BASE_URL}${url}`

  // 默认配置
  const defaultOptions = {
    method: 'GET',
    headers: {
      'Content-Type': 'application/json',
      ...options.headers
    }
    // 不使用 credentials，通过 Authorization 头传递 sessionId
  }

  // 合并配置
  const config = {
    ...defaultOptions,
    ...options
  }

  // 如果是 POST/PUT/PATCH 且有 body 数据，转换为 JSON
  // 排除 FormData 和 URLSearchParams 类型（表单数据）
  if (config.body && typeof config.body === 'object' && 
      !(config.body instanceof FormData) && 
      !(config.body instanceof URLSearchParams)) {
    config.body = JSON.stringify(config.body)
  }

  // 获取 token（如果有）
  const token = localStorage.getItem('token')
  if (token) {
    config.headers['Authorization'] = token
  }

  try {
    console.log(`[${config.method}] 请求:`, fullUrl, config)
    
    const response = await fetch(fullUrl, config)
    
    // 检查 HTTP 状态码
    if (!response.ok) {
      throw new Error(`HTTP Error: ${response.status} ${response.statusText}`)
    }

    // 解析 JSON 响应
    const result = await response.json()
    console.log('[响应]:', result)
    
    // 检查业务状态码，处理401未授权
    if (result.code === 401) {
      // 避免重复跳转
      if (!isRedirectingToLogin) {
        isRedirectingToLogin = true
        
        // 清除本地存储的认证信息
        localStorage.removeItem('token')
        localStorage.removeItem('userInfo')
        
        console.warn('[401未授权] 清除认证信息并跳转到登录页')
        
        // 跳转到登录页
        router.push('/login').then(() => {
          // 跳转完成后重置标记
          setTimeout(() => {
            isRedirectingToLogin = false
          }, 1000)
        }).catch(() => {
          isRedirectingToLogin = false
        })
      }
      
      // 抛出错误，阻止后续请求执行
      const error = new Error(result.message || '登录已过期，请重新登录')
      error.code = 401
      throw error
    }
    
    // 检查业务状态码，处理403权限不足
    if (result.code === 403) {
      console.warn('[403权限不足]:', result.msg || result.message)
      
      // 抛出错误，阻止后续请求执行
      const error = new Error(result.msg || result.message || '权限不足，无法访问该资源')
      error.code = 403
      throw error
    }
    
    return result
  } catch (error) {
    console.error('[请求错误]:', error)
    throw error
  }
}

/**
 * GET 请求
 * @param {string} url - 请求地址
 * @param {object} params - 查询参数
 * @param {object} options - 其他配置
 */
export function get(url, params = {}, options = {}) {
  // 构建查询字符串
  const queryString = Object.keys(params)
    .filter(key => params[key] !== undefined && params[key] !== null && params[key] !== '')
    .map(key => `${encodeURIComponent(key)}=${encodeURIComponent(params[key])}`)
    .join('&')
  
  const fullUrl = queryString ? `${url}?${queryString}` : url
  
  return request(fullUrl, {
    ...options,
    method: 'GET'
  })
}

/**
 * POST 请求
 * @param {string} url - 请求地址
 * @param {object} data - 请求数据
 * @param {object} options - 其他配置
 */
export function post(url, data = {}, options = {}) {
  return request(url, {
    ...options,
    method: 'POST',
    body: data
  })
}

/**
 * PUT 请求
 * @param {string} url - 请求地址
 * @param {object} data - 请求数据
 * @param {object} options - 其他配置
 */
export function put(url, data = {}, options = {}) {
  return request(url, {
    ...options,
    method: 'PUT',
    body: data
  })
}

/**
 * PATCH 请求
 * @param {string} url - 请求地址
 * @param {object} data - 请求数据
 * @param {object} options - 其他配置
 */
export function patch(url, data = {}, options = {}) {
  return request(url, {
    ...options,
    method: 'PATCH',
    body: data
  })
}

/**
 * DELETE 请求
 * @param {string} url - 请求地址
 * @param {object} options - 其他配置
 */
export function del(url, options = {}) {
  return request(url, {
    ...options,
    method: 'DELETE'
  })
}

/**
 * 上传文件
 * @param {string} url - 上传地址
 * @param {FormData} formData - 表单数据
 * @param {object} options - 其他配置
 */
export function upload(url, formData, options = {}) {
  return request(url, {
    ...options,
    method: 'POST',
    body: formData,
    headers: {
      // 不设置 Content-Type，让浏览器自动设置（包含 boundary）
      ...options.headers
    }
  })
}

/**
 * 下载文件
 * @param {string} url - 下载地址
 * @param {string} filename - 文件名
 * @param {object} params - 查询参数
 */
export async function download(url, filename, params = {}) {
  // 构建查询字符串
  const queryString = Object.keys(params)
    .filter(key => params[key] !== undefined && params[key] !== null && params[key] !== '')
    .map(key => `${encodeURIComponent(key)}=${encodeURIComponent(params[key])}`)
    .join('&')
  
  const fullUrl = queryString ? `${API_BASE_URL}${url}?${queryString}` : `${API_BASE_URL}${url}`
  
  try {
    const response = await fetch(fullUrl, {
      method: 'GET',
      headers: {
        'Authorization': localStorage.getItem('token')
      }
    })
    
    if (!response.ok) {
      throw new Error(`下载失败: ${response.statusText}`)
    }
    
    // 尝试检查是否返回的是JSON（可能是错误信息）
    const contentType = response.headers.get('content-type')
    if (contentType && contentType.includes('application/json')) {
      const result = await response.json()
      
      // 检查是否是401未授权
      if (result.code === 401) {
        if (!isRedirectingToLogin) {
          isRedirectingToLogin = true
          localStorage.removeItem('token')
          localStorage.removeItem('userInfo')
          console.warn('[401未授权] 清除认证信息并跳转到登录页')
          router.push('/login').then(() => {
            setTimeout(() => {
              isRedirectingToLogin = false
            }, 1000)
          }).catch(() => {
            isRedirectingToLogin = false
          })
        }
        const error = new Error(result.message || '登录已过期，请重新登录')
        error.code = 401
        throw error
      }
      
      // 检查是否是403权限不足
      if (result.code === 403) {
        console.warn('[403权限不足]:', result.msg || result.message)
        const error = new Error(result.msg || result.message || '权限不足，无法下载该文件')
        error.code = 403
        throw error
      }
      
      throw new Error(result.message || '下载失败')
    }
    
    const blob = await response.blob()
    const link = document.createElement('a')
    link.href = window.URL.createObjectURL(blob)
    link.download = filename
    link.click()
    window.URL.revokeObjectURL(link.href)
  } catch (error) {
    console.error('[下载错误]:', error)
    throw error
  }
}

// 导出环境配置
export const config = {
  baseURL: API_BASE_URL,
  useMock: USE_MOCK,
  env: APP_ENV
}

export default request

